package idv.arthur.work;

import idv.arthur.work.strucs.S3;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.tmatesoft.svn.core.SVNCommitInfo;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNNodeKind;
import org.tmatesoft.svn.core.SVNProperties;
import org.tmatesoft.svn.core.SVNPropertyValue;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory;
import org.tmatesoft.svn.core.io.ISVNEditor;
import org.tmatesoft.svn.core.io.ISVNWorkspaceMediator;
import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
import org.tmatesoft.svn.core.io.diff.SVNDeltaGenerator;
import org.tmatesoft.svn.core.wc.SVNWCUtil;

import com.google.gson.Gson;

public class Withdraw extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public Withdraw() {
        super();
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    	doPost(request,response);
    }

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		Widgets wid = new Widgets();
		request.setCharacterEncoding( wid.UIcodeSet );
		response.setCharacterEncoding( wid.UIcodeSet );
		response.setContentType("application/json");
		
		
		Connection conn = null;
		Connection tarConn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		ResultSet rs2 = null;
		DAVRepositoryFactory.setup();
		String errPars = "}";
		int tmpInt = 0;
		String tmpStr = null;
		
		int localDeplmainSN = 0;		//部署計畫流水號	交					
		int tarDeplmainSN = 0;			//部署計畫流水號	收
		
		int localDeliverySN = 0;		//交付事件流水號	交
		int tarDeliverySN = Integer.parseInt(request.getParameter("deliverSN_q") );

		String comment = request.getParameter("delTaskComment");	// 提交時所撰寫的註解
		RS res = new RS();
		ArrayList<FL> fles = new ArrayList<FL>();
		ArrayList<FL> gfls = new ArrayList<FL>();	//共用程式清單
		
		final String currentUser = request.getParameter("loginUser");
		final String bssId = "MBMS";
		String subSysId = request.getParameter("subSysId");
		String strSQL = "UPDATE deltask SET statusSN=251 WHERE deliverySN=?";	//將狀態同步更新
		InputStream input = null;
		ByteArrayOutputStream baos = null;
		
		SVNRepository tarRepo = null;
		
		try {
			conn = wid.getConn(true);
			int localSysNo = wid.getLocalSysNo( conn, ps, rs);											//取得目前這個系統的身份
			int tarSysNo = Integer.parseInt(request.getParameter("tarSysNo") );		//提交對象的系統的身份
			tarConn = wid.getTarConnection(localSysNo, tarSysNo, conn, ps, rs);		//取得接收方的資料庫連結
			
			final String souStrSVNpar = wid.getTarSVNConnection(localSysNo, tarSysNo, conn, ps, rs,wid.splitTokenONE );	/**	交付端的SVN */
			final String souUSER = souStrSVNpar.split(wid.splitTokenONE)[0];
			final String souPWD = souStrSVNpar.split(wid.splitTokenONE)[1];
			final String souUrl = souStrSVNpar.split(wid.splitTokenONE)[2]+"/"+subSysId;
			
			final String tarStrSVNpar = wid.getTarSVNConnection(localSysNo, localSysNo, conn, ps, rs,wid.splitTokenONE );	/**	接收端的SVN */
			final String tarUSER = tarStrSVNpar.split(wid.splitTokenONE)[0];
			final String tarPWD = tarStrSVNpar.split(wid.splitTokenONE)[1];
			final String tarUrl = tarStrSVNpar.split(wid.splitTokenONE)[2]+"/"+subSysId;
			
			/* 更新任務狀態		交付方  */
			errPars = wid.toJend("tarDeliverySN", tarDeliverySN );
			
			ps = tarConn.prepareStatement(strSQL);
			ps.setInt(1, tarDeliverySN);
			ps.execute();
			
			/* 部署計畫表頭		接收方  */
			localDeplmainSN = wid.getCurrentSN("deplmain", conn, ps, rs);	//取得 本地部署計畫流水號
			strSQL = "INSERT INTO deplmain (deplmainSN,sysSN,creator,createdDateTime,subsysid) VALUES ("+localDeplmainSN+",?,?,?,?)"; 	//寫入部署計畫
			errPars = 
					wid.toJ("tarSysNo", tarSysNo )+
					wid.toJend("currentUser", currentUser);
			
			ps = conn.prepareStatement(strSQL);
			ps.setInt(1, tarSysNo );																														//寫入交付方的系統代號
			ps.setString(2, currentUser );
			ps.setTimestamp(3, wid.currentTimeStamp() );
			ps.setString(4, subSysId );
			ps.execute();
			
			/* 交付事件	接收方 */
			localDeliverySN = wid.getCurrentSN("deltask", conn, ps, rs);
			strSQL = "INSERT INTO deltask (deliverySN,isDeliver,deliveryComment,deliveryTarSN,deplmainSN,souSysSN,tarSysSN,statusSN) VALUES ("+localDeliverySN+",?,?,?,?,?,?,?)";
			errPars = 
					wid.toJ("deliverySN", localDeliverySN )+
					wid.toJ("isDeliver", "f")+
					wid.toJ("deliveryComment", wid.UI2DB( comment,conn.getMetaData().getDatabaseProductName() ) )+
					wid.toJ("deliveryTarSN", tarDeliverySN )+
					wid.toJ("deplmainSN", localDeplmainSN )+
					wid.toJ("souSysSN", tarSysNo )+
					wid.toJ("tarSysSN", localSysNo )+
					wid.toJend("statusSN", 251 );
			
			ps = conn.prepareStatement(strSQL);
			ps.setString(1, "f"); //表示  "不是交付方"
			ps.setString(2, wid.UI2DB( comment,conn.getMetaData().getDatabaseProductName() ) );
			ps.setInt(3, tarDeliverySN);
			ps.setInt(4, localDeplmainSN );
			ps.setInt(5, tarSysNo );
			ps.setInt(6, localSysNo);
			ps.setInt(7, 251);	//交付狀態先寫251，表示交付進行中，待全部完成後回頭修改為1
			ps.execute();
			
			
			/**	去交付方拿 部署細項、需求、需求對應	*/
			strSQL = "SELECT t1.comReqsNum,t4.reqSN,t4.reqid,t4.reqdesc,t2.deplmainSN, t1.depldetailid, t1.localPath, t1.localFile, t1.isnonweb, t1.localVer, t1.depPath FROM depldetail t1, deltask t2, mpreqfiles t3,reqs t4 WHERE t1.deplmainSN=t2.deplmainSN AND t1.depldetailid=t3.depldetailid AND t1.deplmainSN=t3.deplmainSN AND t3.reqSN=t4.reqSN AND t2.deliverySN=? ORDER BY t1.depldetailid ASC";
			errPars = wid.toJend("deliverySN", tarDeliverySN );
			
			ps = tarConn.prepareStatement(strSQL);
			ps.setInt(1, tarDeliverySN);
			rs = ps.executeQuery();
			ArrayList<Cube> cubes = new ArrayList<Cube>();
			int idx = 1;	//用來處理部署細項中的，共用程式
			ArrayList<S3> rqs = null;	//用來記錄共用程式所使用的需求
			
			while ( rs.next() ) {
				if ( rs.getInt("comReqsNum") == 0 || ( rs.getInt("comReqsNum") != 0 &&  idx == 1 ) ) {
					rqs = new ArrayList<S3>();
				}
				
				S3 rq = new S3();
				rq.setA( String.valueOf( rs.getInt("reqSN") ) );
				rq.setB( wid.DB2UI( rs.getString("reqID"),conn.getMetaData().getDatabaseProductName() ) );
				rq.setC( wid.DB2UI( rs.getString("reqdesc"),conn.getMetaData().getDatabaseProductName() ) );
				rqs.add(rq);
				
				if ( rs.getInt("comReqsNum") == 0 ||   idx  ==  rs.getInt("comReqsNum")   ) {
					tarDeplmainSN = rs.getInt("deplmainSN");
					
					Cube cube = new Cube();
					cube.setComReqsNum( rs.getInt("comReqsNum") );
					cube.setIsnonweb( "t".equalsIgnoreCase( rs.getString("isnonweb") ) ) ;									//部署方式 web or non-web
					cube.setDepldetailid( rs.getInt("depldetailid") );																				//	取得部署細項
					cube.setLocalPath( rs.getString("localPath") );
					cube.setLocalFile( rs.getString("localFile") );
					cube.setLocalVer( rs.getInt("localVer") );
					cube.setDepPath( rs.getString("depPath") );
					
					ArrayList<InfoStruc> sqs = new ArrayList<InfoStruc>();
					strSQL = "SELECT subsysid, squadid FROM mpdeplunitsqu WHERE deplmainSN=? AND depldetailid=? AND bssid=?";
					errPars = 
							wid.toJ("deplmainSN", tarDeplmainSN)+
							wid.toJ("depldetailid", rs.getInt("depldetailid"))+
							wid.toJend("bssid", bssId);
					
					ps = tarConn.prepareStatement(strSQL);
					ps.setInt(1, tarDeplmainSN);
					ps.setInt(2, rs.getInt("depldetailid") );
					ps.setString(3, bssId);
					rs2 = ps.executeQuery();
					while (rs2.next()) {
						InfoStruc sq = new InfoStruc();
						sq.setId(rs2.getString("subsysid") );
						sq.setName(rs2.getString("squadid") );
						sqs.add(sq);
					}
					cube.setSqs(sqs);
					cube.setRqs(rqs);
					cubes.add(cube);
					idx=1;
				} else {
					idx++;
				} 
			}
			
			/*errPars = wid.toJ("cubeSize", cubes.size());
			for ( int k=0; k<cubes.size();k++ ) {
				errPars += wid.toJ("ele"+(k+1), cubes.get(k).getLocalFile());	
				errPars += wid.toJ("ver-"+(k+1), cubes.get(k).getLocalVer());
				errPars += wid.toJ("svnPath-"+(k+1), cubes.get(k).getLocalPath());
			}
			errPars += wid.toJend("tarDeplmainSN", tarDeplmainSN);
			wid.kem(conn, ps, new Exception(), wid.toEType("Bug Trace")+errPars, false);*/	
			
			
			/** 在接收端  部署計畫中，寫入交付端的部署計畫代碼 */
			strSQL = "UPDATE deplmain SET tarDeplmainSN=? WHERE deplmainSN=?";
			errPars = 
					wid.toJ("tarDeplmainSN", tarDeplmainSN)+
					wid.toJend("deplmainSN", localDeplmainSN);
			
			ps = conn.prepareStatement(strSQL);
			ps.setInt(1, tarDeplmainSN);
			ps.setInt(2, localDeplmainSN);
			ps.execute();
			
			/** 在交付端  部署計畫中，寫入接收端的部署計畫代碼 */
			errPars = 
					wid.toJ("tarDeplmainSN", localDeplmainSN)+
					wid.toJend("deplmainSN", tarDeplmainSN);
			
			ps = tarConn.prepareStatement(strSQL);
			ps.setInt(1, localDeplmainSN);
			ps.setInt(2, tarDeplmainSN);
			ps.execute();
			
			/* 實體檔案由交付方SVN，寫入接收方SVN */
			errPars = wid.toJend("url", souUrl);
			
			SVNRepository souRepo = SVNRepositoryFactory.create(SVNURL.parseURIEncoded(souUrl));
			errPars = 
					wid.toJ("user", souUSER) + 
					wid.toJend("pwd", souPWD);
			
			ISVNAuthenticationManager authManager = SVNWCUtil.createDefaultAuthenticationManager(souUSER, souPWD);
	        souRepo.setAuthenticationManager(authManager);
	        authManager = SVNWCUtil.createDefaultAuthenticationManager(tarUSER, tarPWD);
	        
	        SVNDeltaGenerator deltaGenerator = new SVNDeltaGenerator();
            String logMessage = "Created at："+System.currentTimeMillis();	//在Commit時送出的Message
            ISVNEditor editor = null;
            SVNCommitInfo info = null;
			
			/*	寫入提領方 部署細項	*/
			ArrayList<S3> fileSoues = new ArrayList<S3>();	//記錄目前已有的路徑檔案版本
	
			/*	A ==>	路徑
			 * 	B ==>		檔名
			 * 	C ==>	版本
			 * */
			int isNotDuplicated = 9999;	//用以確認是否已有同樣路徑、同樣版本的檔案在這次的交付中
			
			for ( int i=0; i<cubes.size(); i++ ) {
				isNotDuplicated=9999;	//-1表示沒有重覆
				
				for (int j=0; j<fileSoues.size(); j++ ) {
					if ( fileSoues.get(j).getA().equalsIgnoreCase( cubes.get(i).getLocalPath() ) && fileSoues.get(j).getB().equalsIgnoreCase( cubes.get(i).getLocalFile() ) && fileSoues.get(j).getC().equalsIgnoreCase( String.valueOf(cubes.get(i).getLocalVer()) )  ) {
						isNotDuplicated=j;		//表示已存在，用原本的版本就好了
						break;
					}
				}
				FL  fl = new FL();
				long localVer = 0;	//接收端的版本
				
				if ( isNotDuplicated==9999 ) {
					/*	至交付方SVN 進行提領檔案的動作	*/
					SVNProperties fileProperties = new SVNProperties();
					baos = new ByteArrayOutputStream(); 
					
					if ("".equalsIgnoreCase( cubes.get(i).getLocalPath() )) {
						tmpStr = souRepo.getRepositoryPath("")+"/"+cubes.get(i).getLocalFile();
					} else {
						tmpStr= souRepo.getRepositoryPath("")+"/"+cubes.get(i).getLocalPath() +"/"+cubes.get(i).getLocalFile();
					}
					
			        souRepo.getFile( tmpStr,cubes.get(i).getLocalVer(), fileProperties, baos);
			        input  = new ByteArrayInputStream(baos.toByteArray() );
			        tarRepo = SVNRepositoryFactory.create( SVNURL.parseURIEncoded( tarUrl ) );
			        tarRepo.setAuthenticationManager(authManager);
			        
			        
			        SVNNodeKind nodeKind = tarRepo.checkPath( cubes.get(i).getLocalPath() ,  -1 );
			        /** ISVNEditor 實體 **/
		            editor = tarRepo.getCommitEditor(logMessage, new CommitMediator() );
		            editor.openRoot(-1);
			        if ( nodeKind == SVNNodeKind.NONE ) {
			        	editor.addDir(subSysId, null, -1 );	//似乎 addDir就連帶變更資料夾了
			        }
		    		
			        try {
			        	editor.openFile( cubes.get(i).getLocalFile(), -1);	/** -1 或 正確的版本都可以 **/	
			        } catch(SVNException e) {
			        	editor.addFile( cubes.get(i).getLocalFile(), null /** 從另一個"路逕" 複製過來 **/, -1 /** 另一個路逕上的那個版本 **/);
			        }
			        
		    		editor.applyTextDelta( cubes.get(i).getLocalFile(), null); 
		    		String baseChecksum = deltaGenerator.sendDelta( cubes.get(i).getLocalFile(), input, editor, true);
		    	    editor.textDeltaEnd( cubes.get(i).getLocalFile() );
		    	    editor.closeFile( cubes.get(i).getLocalFile(), baseChecksum );
		    	    info =  editor.closeEdit();			//本次提交結束		    	    
		    	    
	    	    	fl.setFileName( cubes.get(i).getLocalFile() );	
		    	    
		    	    /**	寫入	*/
		    	    S3 fileSou = new S3();
					fileSou.setA( cubes.get(i).getLocalPath() );
					fileSou.setB( cubes.get(i).getLocalFile() );
					fileSou.setC( String.valueOf( localVer ) );
					fileSoues.add( fileSou );
				} else {
					localVer = Long.parseLong( fileSoues.get(isNotDuplicated).getC() );
		    	    fl.setFileName( fileSoues.get(isNotDuplicated).getB() );
				}
				
				ArrayList<String> reqIds = new ArrayList<String>(); 
				for (int n=0; n< cubes.get(i).getRqs().size(); n++ ) {
					reqIds.add( cubes.get(i).getRqs().get(n).getA() );
				}
				fl.setRqid(reqIds);
				
				if ( cubes.get(i).getComReqsNum() == 0 ) {
					fles.add(fl);	
				} else {
					gfls.add(fl);
				}
				
				int currentReqSN = 0;
				
				/*	比對現存的內容中，是否存在語意相同的的記錄<即, 需求編號(reqid) 和 需求描述(reqdesc) 相同的記錄 > */
				
				for (int m=0; m < cubes.get(i).getRqs().size(); m++ ) {
					strSQL = "SELECT COUNT(reqSN) FROM reqs WHERE reqid=? AND reqdesc=?";
					errPars = 
							wid.toJ("reqid", cubes.get(i).getRqs().get(m).getB())+
							wid.toJend("reqdesc", cubes.get(i).getRqs().get(m).getC() );
					
					ps = conn.prepareStatement(strSQL);
					ps.setString(1, cubes.get(i).getRqs().get(m).getB() );		//需求ID
					ps.setString(2, cubes.get(i).getRqs().get(m).getC() );		//需求中文說明
					rs = ps.executeQuery();
					rs.next();
					if ( rs.getInt(1) == 0 ) {
						/*	新增	 需求  */
						currentReqSN = wid.getCurrentSN("reqs", conn, ps, rs);
						strSQL = "INSERT INTO reqs (reqSN,reqid,reqdesc,sysSN,creator,createdDateTime) VALUES ("+currentReqSN+",?,?,?,?,?)";
						errPars = 
								wid.toJ("reqSN", currentReqSN)+
								wid.toJ("reqid", cubes.get(i).getRqs().get(m).getB() ) + 
								wid.toJ("reqdesc", cubes.get(i).getRqs().get(m).getC() ) +
								wid.toJend("sysSN", tarSysNo );
						
						ps = conn.prepareStatement(strSQL);
						ps.setString(1, cubes.get(i).getRqs().get(m).getB() );
						ps.setString(2, cubes.get(i).getRqs().get(m).getC() );
						ps.setInt(3, tarSysNo);
						ps.setString(4, currentUser);
						ps.setTimestamp(5, wid.currentTimeStamp() );
						ps.execute();	
					} else {	//如果已經存在 語意相同的需求，則要查詢其ID，以供等一下使用
						strSQL = "SELECT MAX(reqSN) FROM reqs WHERE reqid=? AND reqdesc=?";
						errPars = 
								wid.toJ("reqid", cubes.get(i).getRqs().get(m).getB() ) + 
								wid.toJend("reqdesc", cubes.get(i).getRqs().get(m).getC() );
						
						ps = conn.prepareStatement(strSQL);
						ps.setString(1, cubes.get(i).getRqs().get(m).getB() );
						ps.setString(2, cubes.get(i).getRqs().get(m).getC() );
						rs = ps.executeQuery();
						rs.next();
						currentReqSN = rs.getInt(1);
					}
					
					/*	新增	 對應  */
					strSQL = "INSERT INTO mpreqfiles (deplmainSN,depldetailid,reqSN,creator,createdDateTime) VALUES (?,?,?,?,?)";
					errPars = 
							wid.toJ("deplmainSN", localDeplmainSN)+
							wid.toJ("depldetailid", cubes.get(i).getDepldetailid() ) + 
							wid.toJend("reqSN", currentReqSN );
					
					ps = conn.prepareStatement(strSQL);
					ps.setInt(1, localDeplmainSN);
					ps.setInt(2, cubes.get(i).getDepldetailid() );
					ps.setInt(3, currentReqSN);
					ps.setString(4, currentUser);
					ps.setTimestamp(5, wid.currentTimeStamp() );
					ps.execute();
				}
				
				/* 記錄程式要部署到那些Squad		接收方 */
				strSQL = "INSERT INTO mpdeplunitsqu (deplmainSN,depldetailid,bssid,subsysid,squadid,creator,createdDateTime) VALUES (?,?,?,?,?,?,?)";
				ps = conn.prepareStatement(strSQL);
				for(int j=0;j<cubes.get(i).getSqs().size();j++) {
					errPars = 
							wid.toJ("deplmainSN", localDeplmainSN)+
							wid.toJ("depldetailid", cubes.get(i).getDepldetailid() )+
							wid.toJ("bssid", bssId)+wid.toJ("subsysid", cubes.get(i).getSqs().get(j).getId() ) + 
							wid.toJend("squadid", cubes.get(i).getSqs().get(j).getName() );
					
					ps.setInt(1, localDeplmainSN);
					ps.setInt(2, cubes.get(i).getDepldetailid() );
					ps.setString(3, bssId);
					ps.setString(4, cubes.get(i).getSqs().get(j).getId() );
					ps.setString(5, cubes.get(i).getSqs().get(j).getName() );
					ps.setString(6, currentUser);
					ps.setTimestamp(7, wid.currentTimeStamp() );
					ps.execute();
				}
			}
    	    Long localVer = info.getNewRevision();			//本次提交的版次
			
			
			for ( int i=0; i<cubes.size(); i++ ) {
				/* 記錄  SVN交付記錄( delsvn ) 交付方 */
				tmpInt =wid.getCurrentSN("delsvn", tarConn, ps, rs2); 
	    	    strSQL = "INSERT INTO delsvn (svnMappingSN,deliverySN,fromPath,fromFile,fromVer,toPath,toFile,toVer,sysSN,fromSVNhost,toSVNhost) VALUES ("+tmpInt+",?,?,?,?,?,?,?,?,?,?)";
	    	    errPars =
	    	    		wid.toJ("svnMappingSN", tmpInt)+
	    	    		wid.toJ("deliverySN", tarDeliverySN )+
	    	    		wid.toJ("fromPath",  cubes.get(i).getLocalPath() )+
	    	    		wid.toJ("fromFile", cubes.get(i).getLocalFile() )+
	    	    		wid.toJ("fromVer", cubes.get(i).getLocalVer() )+
	    	    		wid.toJ("toPath", cubes.get(i).getLocalPath() )+
	    	    		wid.toJ("toFile", cubes.get(i).getLocalFile() )+
	    	    		wid.toJ("toVer", localVer )+
	    	    		wid.toJ("sysSN", localSysNo)+
	    	    		wid.toJ("fromSVNhost", tarRepo.getLocation().getHost() )+
	    	    		wid.toJend("toSVNhost", souRepo.getLocation().getHost() );
	    	    		
	    	    ps = tarConn.prepareStatement(strSQL);
	    	    ps.setInt(1, tarDeliverySN);														/*	交付方 交付代碼		*/											
	    	    ps.setString(2, cubes.get(i).getLocalPath() );						/*	交付方	SVN相對路徑		*/
	    	    ps.setString(3, cubes.get(i).getLocalFile() );							/*	交付方 檔案名稱		*/
	    	    ps.setInt(4, cubes.get(i).getLocalVer() );								/*	交付方	版次		*/
	    	    ps.setString(5, cubes.get(i).getLocalPath() );						/*	接收方 SVN相對路徑		*/
	    	    ps.setString(6, cubes.get(i).getLocalFile() );							/*	接收方 檔案名稱		*/
	    	    ps.setLong(7, localVer);															/*	接收方	版次		*/
	    	    ps.setInt(8, localSysNo);															/*	交付端給了誰 (他給了誰)		*/
	    	    ps.setString(9, tarRepo.getLocation().getHost() );				/*	交付方 主機		*/
	    	    ps.setString(10, souRepo.getLocation().getHost() );			/*	接收方 主機		*/
	    	    ps.execute();
	    	    
	    	    /* 記錄  SVN交付記錄( delsvn ) 接收方 */
	    	    tmpInt = wid.getCurrentSN("delsvn", conn, ps, rs2);
	    	    strSQL = "INSERT INTO delsvn (svnMappingSN,deliverySN,fromPath,fromFile,fromVer,toPath,toFile,toVer,sysSN,fromSVNhost,toSVNhost) VALUES ("+tmpInt+",?,?,?,?,?,?,?,?,?,?)";
	    	    errPars =
	    	    		wid.toJ("svnMappingSN", tmpInt)+
	    	    		wid.toJ("deliverySN", localDeliverySN )+
	    	    		wid.toJ("fromPath",  cubes.get(i).getLocalPath() )+
	    	    		wid.toJ("fromFile", cubes.get(i).getLocalFile() )+
	    	    		wid.toJ("fromVer", cubes.get(i).getLocalVer() )+
	    	    		wid.toJ("toPath", cubes.get(i).getLocalPath() )+
	    	    		wid.toJ("toFile", cubes.get(i).getLocalFile() )+
	    	    		wid.toJ("toVer", localVer )+
	    	    		wid.toJ("sysSN", tarSysNo)+
	    	    		wid.toJ("fromSVNhost", tarRepo.getLocation().getHost() )+
	    	    		wid.toJend("toSVNhost", souRepo.getLocation().getHost() );
	    	    
	    	    ps = conn.prepareStatement(strSQL);
	    	    ps.setInt(1, localDeliverySN);													/*	接收方 交付代碼	*/
	    	    ps.setString(2, cubes.get(i).getLocalPath() );						/*	交付方	SVN相對路徑		*/
	    	    ps.setString(3, cubes.get(i).getLocalFile() );							/*	交付方 檔案名稱		*/
	    	    ps.setLong(4, cubes.get(i).getLocalVer() );							/*	交付方	版次		*/
	    	    ps.setString(5, cubes.get(i).getLocalPath() );				/*	接收方 SVN相對路徑		*/
	    	    ps.setString(6, cubes.get(i).getLocalFile() );							/*	接收方 檔案名稱		*/
	    	    ps.setLong(7, localVer);																/*	接收方	版次		*/
	    	    ps.setInt(8, tarSysNo);																	/*	誰給了你		*/
	    	    ps.setString(9, tarRepo.getLocation().getHost() );				/*	交付方 主機		*/
	    	    ps.setString(10, souRepo.getLocation().getHost() );			/*	接收方 主機		*/
	    	    ps.execute();
				
	    	    /*	部署計劃	寫入接收方	*/
				strSQL = "INSERT INTO depldetail (deplmainSN,depldetailid,localPath,localFile,localVer,depPath,comReqsNum,creator,createdDateTime, isnonweb) VALUES (?,?,?,?,?,?,?,?,?,?)";
				
				errPars =
	    	    		wid.toJ("deplmainSN", localDeplmainSN)+
	    	    		wid.toJ("depldetailid", cubes.get(i).getDepldetailid() )+
	    	    		wid.toJ("localPath",  cubes.get(i).getLocalPath() )+
	    	    		wid.toJ("localFile", cubes.get(i).getLocalFile() )+
	    	    		wid.toJ("localVer", localVer )+
	    	    		wid.toJ("depPath", cubes.get(i).getDepPath() )+
	    	    		wid.toJend("comReqsNum", cubes.get(i).getComReqsNum() );
				
				ps = conn.prepareStatement(strSQL);
				ps.setInt(1, localDeplmainSN);									//本地部署計畫代碼
				ps.setInt(2, cubes.get(i).getDepldetailid() );				//部署細項代碼
				ps.setString(3, cubes.get(i).getLocalPath() );			//本地端 SVN路徑
				ps.setString(4, cubes.get(i).getLocalFile() );				//本地端 檔案名稱
				ps.setLong(5, localVer);												//本地端 版次
				ps.setString(6, cubes.get(i).getDepPath() );				//本地端 部署延伸路徑
				ps.setInt(7, cubes.get(i).getComReqsNum() );			//共同需求項數
				ps.setString(8, currentUser);										//部署細項建立人員 (表示誰執行了這個提領)
				ps.setTimestamp(9, wid.currentTimeStamp() );		//部署細項建立時間
				ps.setString(10, cubes.get(i).isnonweb?"t":"f" );		//部署方式 non-web or web 
				ps.execute();
			}
			
			
			/*	將狀態改為提領完成	*/
			strSQL = "UPDATE deltask SET statusSN=3, deliveryTarSN=? WHERE deliverySN=?";
			errPars =
    	    		wid.toJ("deliveryTarSN", localDeliverySN)+
    	    		wid.toJend("deliverySN", tarDeliverySN );
    	    		
			ps = tarConn.prepareStatement(strSQL);
			ps.setInt(1, localDeliverySN);
			ps.setInt(2, tarDeliverySN);
			ps.execute();
			strSQL = "UPDATE deltask SET statusSN=3 WHERE deliverySN=?";
			errPars =
    	    		wid.toJend("deliverySN", localDeliverySN);
			
			ps = conn.prepareStatement(strSQL);
			ps.setInt(1, localDeliverySN);
			ps.execute();
			
			res.setGfls(gfls);
			res.setFles(fles);
			res.setVer(localVer);		// 將本次提交的版次
			
		} catch ( SQLException e) {
			res.setErrorMessage( wid.kem(conn, ps, e, wid.toEType("SQLException")+errPars, true) );
		} catch ( SVNException e) {
			res.setErrorMessage( wid.kem(conn, ps, e, wid.toEType("SVNException")+errPars, true) );
		} catch ( Exception e) {
			res.setErrorMessage( wid.kem(conn, ps, e, wid.toEType("Exception")+errPars, true) );
		} finally {
			try {
				if ( input != null ) { input.close(); }
				if ( baos != null ) { baos.close(); }
				if ( rs != null ) { rs.close(); }
				if ( rs2 != null ) { rs2.close(); }
				if ( ps!= null ) { ps.close(); }
				if ( conn!= null ) { conn.close(); }
				if ( tarConn!= null ) { tarConn.close(); }
			} catch (SQLException e) {
				System.out.println(wid.errProcess(e));
			}
		}
		
		response.getWriter().write(new Gson().toJson(res));
	}
}

class CommitMediator implements ISVNWorkspaceMediator {
	private Map<Object, ByteArrayOutputStream> myTmpStorages = new HashMap<Object, ByteArrayOutputStream>();

	public SVNPropertyValue getWorkspaceProperty(String path, String name)
			throws SVNException {
		return null;
	}

	public void setWorkspaceProperty(String path, String name, String value)
			throws SVNException {
	}

	public OutputStream createTemporaryLocation(String path, Object id)
			throws IOException {
		ByteArrayOutputStream tempStorageOS = new ByteArrayOutputStream();
		myTmpStorages.put(id, tempStorageOS);
		return tempStorageOS;
	}

	public InputStream getTemporaryLocation(Object id) throws IOException {
		return new ByteArrayInputStream(
				((ByteArrayOutputStream) myTmpStorages.get(id))
						.toByteArray() );
	}

	public long getLength(Object id) throws IOException {
		ByteArrayOutputStream tempStorageOS = (ByteArrayOutputStream) myTmpStorages
				.get(id);
		if (tempStorageOS != null) {
			return tempStorageOS.size();
		}
		return 0;
	}

	public void deleteTemporaryLocation(Object id) {
		myTmpStorages.remove(id);
	}

	public void setWorkspaceProperty(String path, String name,
			SVNPropertyValue value) throws SVNException {
	}
}